﻿#include "MainWindow.h"
#include "ui_MainWindow.h"

#include <QDebug>
#include <QFileDialog>
#include <QMessageBox>
#include <QMetaType>
#include <QElapsedTimer>

#if _MSC_VER >= 1600
//#pragma execution_character_set("utf-8")
#endif


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_timer = new QTimer;
    m_timer->setInterval(1000);

    this->setWindowTitle("智能加速度测量系统@电子装备结构设计教育部重点实验室");
    //y轴自适应线程
    AxisAdjust* axisAdjust = new AxisAdjust;
    axisAdjust->moveToThread(&axisAdjustThread);
    qRegisterMetaType<QVector<qreal>>("QVector<qreal>");
//    connect(&axisAdjustThread, &QThread::finished, axisAdjust, &QObject::deleteLater);
    connect(this, &MainWindow::ampOperator, axisAdjust, &AxisAdjust::doAdjust);
    connect(axisAdjust, &AxisAdjust::resultReady, this, &MainWindow::handleAmpResults);
    axisAdjustThread.start();
    axisAdjustThread.setPriority(QThread::LowPriority);
    //数据处理线程
    DataDisposal* dadadispos = new DataDisposal;
    dadadispos->moveToThread(&dataDisposalThread);
//    connect(&dataDisposalThread, &QThread::finished, dadadispos, &QObject::deleteLater);

    connect(dadadispos, &DataDisposal::dataReady, this, &MainWindow::readData);
    dataDisposalThread.start();
//    dataDisposalThread.setPriority(QThread::HighPriority);
    //chart Init
    InitChart();
    labNote = new QLabel;
    labRevCnt = new QLabel;
    labRevCnt->setText("共接收 0 组 数据");
    labRevCnt->setMinimumWidth(200);
    ui->statusBar->addWidget(labRevCnt);
    ui->statusBar->addWidget(labNote);
    /*
     * Bluetooth instance
     *
     * This is an instance of the bluetooth class for
     * communication between the UART friend and this program
     */
    this->bluetooth = new Bluetooth(this);

    connect(bluetooth, SIGNAL(deviceListAvailable()), this, SLOT(refreshDeviceList()));
    connect(bluetooth, SIGNAL(deviceConnected()), this, SLOT(handleBluetoothConnect()));
    connect(bluetooth, SIGNAL(deviceDisconnected()), this, SLOT(handleBluetoothDisconnect()));
    connect(bluetooth, SIGNAL(deviceTransmitReady()), this, SLOT(handleTransmitReady()));
    connect(bluetooth, &Bluetooth::dataAvailable, dadadispos, &DataDisposal::doDisposal);
//    connect(bluetooth,SIGNAL(dataAvailable()),this,SLOT(readData()));
    connect(m_timer, SIGNAL(timeout()), this, SLOT(receivedDataCount()));

    this->bluetooth->refreshDeviceList();
    /*
     * Timeout Timer
     *
     * This timer is used to timeout device connectinos that take too long
     */
    timeoutTimer = new QTimer(this);
    connect(timeoutTimer, SIGNAL(timeout()), this, SLOT(connectionTimeout()));

    ui->textShowAccG->setAlignment(Qt::AlignCenter);
    ui->textShowAccnoG->setAlignment(Qt::AlignCenter);
    ui->textShowAng->setAlignment(Qt::AlignCenter);
}

MainWindow::~MainWindow()
{
    delete ui;
    delete vecTime;
    delete vecRelativeTime;
    delete vecAccWithG;
    delete vecAccNoG;
    delete vecAng;
    axisAdjustThread.quit();
    axisAdjustThread.wait();
    dataDisposalThread.quit();
    dataDisposalThread.wait();
}

void MainWindow::startConnectTimeoutTimer()
{
    if(!timeoutTimer){
        timeoutTimer = new QTimer(this);
        connect(timeoutTimer, SIGNAL(timeout()), this, SLOT(connectionTimeout()));
    }
    timeoutTimer->start(5000);
}

void MainWindow::refreshDeviceList()
{
    if(bluetooth){
        QStringList devices = this->bluetooth->getDeviceList();
        ui->BluetoothDevicesBox->clear();
        ui->BluetoothDevicesBox->addItems(devices);
    }
}

void MainWindow::handleBluetoothConnect()
{
    if(bluetooth){
        this->timeoutTimer->stop();
        QString txt = "Connected to " + bluetooth->getDeviceName();
        ui->StatusLabel->setText(txt);
        ui->ConnectButton->setText("断开连接");
        this->state = CONNECTED;
    }
}

void MainWindow::handleBluetoothDisconnect()
{
    if(bluetooth){
        QString txt = "Disconnected from " + bluetooth->getDeviceName();
        ui->StatusLabel->setText(txt);
        ui->ConnectButton->setText("连接");
        this->state = DISCONNECTED;
    }
}

void MainWindow::handleTransmitReady()
{
    if(bluetooth){
        qDebug() << "ready!";
        this->state = READY;
        bluetooth->write("Death and despair!");
    }
}


void MainWindow::sendUserInput(char c)
{
    if(bluetooth){
        bluetooth->write(c);
    }
}

//接收到6个数，分别是AccX最小最大...
void MainWindow::handleAmpResults(const QVector<qreal> ampList)
{
    if(ampList.size() != 6){
        qDebug() << "handleAmpResults() error";
        return;
    }
    ui->plotX->yAxis->setRange(ampList[0], ampList[1]);
    ui->plotY->yAxis->setRange(ampList[2], ampList[3]);
    ui->plotZ->yAxis->setRange(ampList[4], ampList[5]);
}


void MainWindow::connectionTimeout()
{
    qDebug() << "Conntimeout";
    this->state = DISCONNECTED;
    ui->StatusLabel->setText("Failed to connect to device");
}

void MainWindow::on_RefreshDevicesButton_released()
{
    if(bluetooth){
        bluetooth->refreshDeviceList();
    }
}

void MainWindow::on_ConnectButton_released()
{
    if(bluetooth){
        if(this->state == DISCONNECTED){
            QString deviceName = ui->BluetoothDevicesBox->currentText();
            if(!deviceName.isEmpty()){
                ui->StatusLabel->setText("Connecting...");
                this->startConnectTimeoutTimer();
                bluetooth->connectToDevice(deviceName);
                RevCnt = 0;
                m_timer->start();
            }
        }
        else{
            bluetooth->disconnectFromDevice();
            m_timer->stop();
        }
    }
}

void MainWindow::InitChart()
{
    this->vecTime=new QVector<QTime>();
    this->vecRelativeTime = new QVector<qreal>;
    this->vecAccWithG=new QVector<QVector<qreal>>(3);
    this->vecAccNoG=new QVector<QVector<qreal>>(3);
    this->vecAng=new QVector<QVector<qreal>>(3);

    QSharedPointer<QCPAxisTickerTime> timeTicker(new QCPAxisTickerTime);
    timeTicker->setTickStepStrategy(QCPAxisTicker::tssMeetTickCount);
    timeTicker->setTimeFormat("%s");
    timeTicker->setTickCount(10);
    //设置刻度间距宽度
    timeTicker->setFieldWidth(QCPAxisTickerTime::TimeUnit::tuMilliseconds,10);

    //AccX曲线
    ui->plotX->addGraph();
    ui->plotX->graph(0)->setPen(QPen(Qt::red,2));
    ui->plotX->setVisible(true);
    ui->plotX->xAxis->setRange(0,baseRange);
    ui->plotX->yAxis->setRange(-1,1);
    ui->plotX->xAxis->setTicker(timeTicker);
//    ui->plotX->xAxis->setLabel("Time");
    ui->plotX->yAxis->setLabel("AccX/g");
    ui->plotX->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);
    //AccY曲线
    ui->plotY->addGraph();
    ui->plotY->graph(0)->setPen(QPen(Qt::green,2));
    ui->plotY->setVisible(true);
    ui->plotY->xAxis->setRange(0,baseRange);
    ui->plotY->yAxis->setRange(-1,1);
    ui->plotY->xAxis->setTicker(timeTicker);
//    ui->plotY->xAxis->setLabel("Time");
    ui->plotY->yAxis->setLabel("AccY/g");
    ui->plotY->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);
    //AccZ曲线
    ui->plotZ->addGraph();
    ui->plotZ->graph(0)->setPen(QPen(Qt::blue,2));
    ui->plotZ->setVisible(true);
    ui->plotZ->xAxis->setRange(0,baseRange);
    ui->plotZ->yAxis->setRange(-1,1);
    ui->plotZ->xAxis->setTicker(timeTicker);
//    ui->plotZ->xAxis->setLabel("Time");
    ui->plotZ->yAxis->setLabel("AccZ/g");
    ui->plotZ->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);
}


void MainWindow::readData(const QVector<qreal> dataList)
{
    if(!recFlag) return;
    QElapsedTimer timer;
    timer.start();
    /*0-2有重力加速度的数据
      3-5没有重力加速度的数据
      6-8角度数据*/
    if(dataList.size() == 9){
        vecAccWithG->push_back(dataList.mid(0,3));
        vecAccNoG->push_back(dataList.mid(3,3));
        vecAng->push_back(dataList.mid(6,3));
        RevCnt++;
        labRevCnt->setText(QString::asprintf("共接收 %d 组数据",RevCnt));
    }
    else{
        labNote->setText("readData() 错误");
        return;
    }
    //显示数据
    ui->textShowAccG->clear();
    ui->textShowAccnoG->clear();
    ui->textShowAng->clear();
    ui->textShowAccG->append(QString::asprintf("原始加速度/g\r\nAccX: %-6.3f\r\nAccY: %-6.3f\r\nAccZ: %-6.3f",
                                               vecAccWithG->last()[0],vecAccWithG->last()[1],vecAccWithG->last()[2]));
    ui->textShowAccnoG->append(QString::asprintf("线性加速度/g\r\nAccX: %-6.3f\r\nAccY: %-6.3f\r\nAccZ: %-6.3f",
                                               vecAccNoG->last()[0],vecAccNoG->last()[1],vecAccNoG->last()[2]));
    ui->textShowAng->append(QString::asprintf("倾角/°\r\nX: %-6.3f\r\nY: %-6.3f\r\nZ: %-6.3f",
                                               vecAng->last()[0],vecAng->last()[1],vecAng->last()[2]));
    //paint
    QVector<qreal> data;
    int index = ui->comboBoxDataChoice->currentIndex();
    switch(index){
        case 0: data = vecAccNoG->last();break;
        case 1: data = vecAccWithG->last();break;
        case 2: data = vecAng->last();break;
    }
    //画图
    QTime curTime=QTime::currentTime();
    vecTime->push_back(curTime);
    double nowtime = -curTime.msecsTo((*vecTime)[0]);
    nowtime /= 1000;
    vecRelativeTime->push_back(nowtime);
    //数据接收区
    ui->dataRec->appendPlainText("Current time: " + curTime.toString());
    ui->dataRec->appendPlainText(QString::asprintf("%-15sAccX:  %-6.3fG  AccY:  %-6.3fG  AccZ:  %-6.3fG\r\n"
                                                   "%-15sAccX:  %-6.3fG  AccY:  %-6.3fG  AccZ:  %-6.3fG\r\n"
                                                   "%-15s   X:  %-6.3f°    Y:  %-6.3f°    Z:  %-6.3f°\r\n",
                                               "Original Acc", vecAccWithG->last()[0], vecAccWithG->last()[1], vecAccWithG->last()[2],
                                               "After filter", vecAccNoG->last()[0], vecAccNoG->last()[1], vecAccNoG->last()[2],
                                               "Angle", vecAng->last()[0], vecAng->last()[1], vecAng->last()[2]));
//qDebug() << "start time = " << (*vecTime)[0] << "   Current Time " << curTime.toString()  <<  "   timer = " << nowtime;
    if(ui->checkBoxShowAll->isChecked() == true){
        ui->plotX->xAxis->setRange(0,nowtime);
        ui->plotY->xAxis->setRange(0,nowtime);
        ui->plotZ->xAxis->setRange(0,nowtime);
    }
    else{
        if(nowtime > 10){
            ui->plotX->xAxis->setRange(nowtime-baseRange,nowtime);
            ui->plotY->xAxis->setRange(nowtime-baseRange,nowtime);
            ui->plotZ->xAxis->setRange(nowtime-baseRange,nowtime);
        }
    }
//qDebug() << "data: " << data[0] << " " << data[1] << " " << data[2];
    ui->plotX->graph()->addData(nowtime,data[0]);
    ui->plotY->graph()->addData(nowtime,data[1]);
    ui->plotZ->graph()->addData(nowtime,data[2]);
    ui->plotX->replot();
    ui->plotY->replot();
    ui->plotZ->replot();

#if axisThread   //y轴自适应，未调试好
    //准备发送给调整y轴线程的参数
    QVector<qreal> operateData(data);
//    operateData.push_back((axisList[0]->max()-axisList[0]->min())/step);
qDebug() << "range = " << ui->plotX->xAxis->range().size();
    operateData.push_back(nowtime);
    operateData.push_back(ui->plotX->xAxis->range().size()/0.1);
    operateData.push_back(ui->checkBoxShowAll->isChecked() ? 1 : 0);
    //发送数据，5个数，前三个是数据，第四位时间，后面分别是x轴范围以及是否开启“显示全图”
    emit ampOperator(operateData);
#endif
qDebug() << "readData() cost " << timer.elapsed() << " ms in " << QThread::currentThread();
}

void MainWindow::on_btnDataOutput_clicked()
{
    QString textfileName = QFileDialog::getSaveFileName(this, "export","","*.txt");
    QFile file(textfileName);
    if(!file.open(QFile::WriteOnly|QFile::Text))
        return;
    QTextStream out(&file);  //QTextStream会自动将 Unicode 编码同操作系统的编码进行转换
    out << ui->dataRec->toPlainText();
    labNote->setText("数据已导出");
}

void MainWindow::on_btnImageClear_clicked()
{
    QVector<double> vecEmpty;
    vecTime->clear();
    vecRelativeTime->clear();
//    ui->plotX->clearItems();
    ui->plotX->graph()->setData(vecEmpty,vecEmpty);
    ui->plotX->xAxis->setRange(0, baseRange);
//    ui->plotY->clearItems();
    ui->plotY->graph()->setData(vecEmpty,vecEmpty);
    ui->plotY->xAxis->setRange(0, baseRange);
//    ui->plotZ->clearItems();
    ui->plotZ->graph()->setData(vecEmpty,vecEmpty);
    ui->plotZ->xAxis->setRange(0, baseRange);
    //更新图表
    ui->plotX->replot();
    ui->plotY->replot();
    ui->plotZ->replot();
    labNote->setText("图表/数据接收区已清除");
}

void MainWindow::on_btnClearRev_clicked()
{
    ui->dataRec->clear();
    labNote->setText("数据接收区已清除");
}

int befCnt = 0;
void MainWindow::receivedDataCount()
{
    labNote->setText(QString::asprintf("数据接收速度： %d /s ", RevCnt-befCnt));
    befCnt = RevCnt;
}



void MainWindow::on_btnStop_clicked()
{
    recFlag = !recFlag;
    if(recFlag)
        ui->btnStop->setText("停止接收");
    else{
        ui->btnStop->setText("开始接收");
    }
}

void MainWindow::on_comboBoxAmpOfAxis_currentTextChanged(const QString &arg1)
{
    double amp = arg1.toDouble();
    ui->plotX->yAxis->setRange(-amp, amp);
    ui->plotY->yAxis->setRange(-amp, amp);
    ui->plotZ->yAxis->setRange(-amp, amp);
}

#if axisThread
void MainWindow::on_checkBoxShowAll_clicked(bool checked)
{
    if(checked){

}
#endif
